/**
 * 统一的API错误处理工具模块
 * 
 * 本模块提供了一套全局性的错误处理机制，用于统一处理API请求过程中产生的各类错误。
 * 设计目标是标准化错误处理流程，提高用户体验，并简化开发过程中的错误处理逻辑。
 * 
 * 主要功能：
 * - API错误信息展示（消息提示或通知形式）
 * - 不同HTTP状态码的特殊处理（如401自动跳转到登录页）
 * - 错误对象的标准化和转换
 * - 可配置的错误处理选项
 * 
 * 使用方式：
 * 在API调用的catch块中调用这些函数，可以自动处理错误展示和后续逻辑
 * 
 * @module utils/errorHandler
 */
import { message, notification } from 'antd';
import { ApiError } from '../types/api';

/**
 * 显示API错误消息
 * 根据错误类型和状态码智能选择错误展示方式
 * 
 * @param error API错误对象，可能是Error实例、ApiError或字符串
 * @param showNotification 是否以通知形式显示错误，默认为false（使用消息提示）
 */
export const showApiError = (error: unknown, showNotification = false): void => {
  // 默认错误消息和描述
  let errorMessage = '操作失败，请重试';
  let errorDescription = '服务器异常，请联系管理员';
  let status = 500;

  if (error instanceof Error) {
    // 处理标准Error对象或ApiError对象
    const apiError = error as ApiError;
    if (apiError.response) {
      status = apiError.response.status;
      
      // 从响应中提取详细错误信息
      if (apiError.response.data) {
        errorMessage = apiError.response.data.msg || apiError.message || errorMessage;
        errorDescription = apiError.response.data.error || apiError.response.data.msg || errorDescription;
      }
    } else {
      // 非API错误，可能是网络错误或客户端异常
      errorMessage = error.message;
      errorDescription = '请检查网络连接或联系管理员';
    }
  } else if (typeof error === 'string') {
    // 直接使用字符串作为错误信息
    errorMessage = error;
    errorDescription = error;
  }

  // 根据HTTP状态码进行特殊处理
  if (status === 401) {
    // 401状态码：未授权错误，通常是token过期或无效
    errorMessage = '登录已过期，请重新登录';
    errorDescription = '您的登录状态已失效，请重新登录';
    
    // 清除本地存储的认证信息
    localStorage.removeItem('token');
    localStorage.removeItem('userInfo');
    
    // 重定向到登录页面
    window.location.href = '/login';
  } else if (status === 403) {
    // 403状态码：禁止访问，权限不足
    errorMessage = '无权访问';
    errorDescription = '您没有权限执行此操作';
  } else if (status === 404) {
    // 404状态码：请求的资源不存在
    errorMessage = '资源不存在';
    errorDescription = '您请求的资源不存在';
  }

  // 根据参数选择展示方式
  if (showNotification) {
    // 使用通知形式展示错误（适合需要展示详细信息的场景）
    notification.error({
      message: errorMessage,
      description: errorDescription,
      duration: 4,
    });
  } else {
    // 使用简单消息提示（适合简单错误提示）
    message.error(errorMessage);
  }
};

/**
 * 处理API错误的高级函数
 * 提供更多配置选项，并返回标准化的错误对象
 * 
 * @param error API错误对象
 * @param options 处理选项对象
 * @param options.showMessage 是否显示错误消息，默认为true
 * @param options.showNotification 是否以通知形式显示，默认为false
 * @param options.rethrow 是否重新抛出错误，默认为false
 * @returns 标准化后的Error对象
 */
export const handleApiError = (
  error: unknown, 
  options: {
    showMessage?: boolean;
    showNotification?: boolean;
    rethrow?: boolean;
  } = {}
): Error => {
  const { 
    showMessage = true,
    showNotification = false,
    rethrow = false
  } = options;
  
  // 显示错误消息
  if (showMessage) {
    showApiError(error, showNotification);
  }
  
  // 将错误对象转换为标准Error类型
  const standardError = error instanceof Error ? error : new Error(String(error));
  
  // 如果需要重新抛出错误
  if (rethrow) {
    throw standardError;
  }
  
  return standardError;
};

export default {
  showApiError,
  handleApiError,
}; 